package top.goldenyear.porpoise.system.setting.service;

import com.easy.query.api.proxy.client.EasyEntityQuery;
import com.easy.query.solon.annotation.Db;
import org.noear.solon.data.annotation.Ds;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import cn.hutool.v7.core.text.StrUtil;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import top.goldenyear.porpoise.common.core.exception.ErrorCode;
import top.goldenyear.porpoise.common.core.exception.ServiceException;
import top.goldenyear.porpoise.framework.web.core.model.PageResult;
import top.goldenyear.porpoise.framework.web.core.model.query.QPage;
import top.goldenyear.porpoise.framework.web.core.service.BaseService;
import top.goldenyear.porpoise.system.setting.dto.ConfigCategorySearchReq;
import top.goldenyear.porpoise.system.setting.model.Config;
import top.goldenyear.porpoise.system.setting.model.ConfigCategory;
import top.goldenyear.porpoise.system.setting.model.proxy.ConfigCategoryProxy;

/**
 * 配置类型表 Service 服务层
 *
 * @author airhead
 * @since 2024-10-15
 */
@Component
@Slf4j
public class ConfigCategoryService extends BaseService<ConfigCategory, ConfigCategoryProxy> {
  @Db
  private EasyEntityQuery easyEntityQuery;
  @Inject private ConfigService configService;

  public ConfigCategoryService() {
    super(ConfigCategory.class, ConfigCategoryProxy.class);
  }

  public Boolean createConfigCategory(ConfigCategory configCategory) {
    Boolean exists = exists("code", configCategory.getCode(), "id", null);
    if (exists) {
      throw new ServiceException(
          ErrorCode.builder().msg(String.format("配置类别已存在, %s", configCategory.getCode())).build());
    }

    return save(configCategory);
  }

  public Boolean updateConfigCategory(ConfigCategory configCategory) {
    ConfigCategory dbCategory = getById(configCategory.getId());
    if (dbCategory == null) {
      throw new ServiceException(
          ErrorCode.builder().msg(String.format("配置类别不存在, %d", configCategory.getId())).build());
    }

    boolean changeCode = !dbCategory.getCode().equals(configCategory.getCode());
    if (changeCode) {
      Boolean exists = exists("code", configCategory.getCode(), "id", configCategory.getId());
      if (exists) {
        throw new ServiceException(
            ErrorCode.builder()
                .msg(String.format("配置类别已存在, %s", configCategory.getCode()))
                .build());
      }
    }

    boolean update = updateById(configCategory);
    if (update && changeCode) {
      if (StrUtil.isNotBlank(dbCategory.getCode())) {
        Config query = new Config();
        query.setCategoryCode(dbCategory.getCode());
        List<Config> configList = configService.list(query);
        for (Config config : configList) {
          config.setCategoryCode(configCategory.getCode());
        }

        configService.batchUpdate(configList);
      }
    }

    return update;
  }

  public ConfigCategory getConfigCategory(Integer id) {
    return getById(id);
  }

  public Boolean deleteConfigCategory(Integer id) {
    ConfigCategory category = getById(id);
    if (category == null) {
      throw new ServiceException(ErrorCode.builder().msg(String.format("配置类别不存在, %d", id)).build());
    }

    Config query = new Config();
    query.setCategoryCode(category.getCode());
    long count = configService.count(query);
    if (count > 0) {
      throw new ServiceException(ErrorCode.builder().msg("配置类别下已存在配置，请先删除配置").build());
    }

    return deleteById(id);
  }

  public Boolean batchDelConfigCategory(List<Integer> ids) {
    for (Integer id : ids) {
      if (getById(id) == null) {
        throw new ServiceException(
            ErrorCode.builder().msg(String.format("配置类别不存在, %d", id)).build());
      }
    }

    return deleteByIds(ids);
  }

  public List<ConfigCategory> listConfigCategory(ConfigCategory configCategory) {
    return list(configCategory);
  }

  public PageResult<ConfigCategory> paginateConfigCategory(
      QPage qPage, ConfigCategorySearchReq searchReq) {
    return paginate(
        qPage,
        configCategoryProxy -> {
          configCategoryProxy.status().eq(searchReq.getStatus());
          configCategoryProxy.or(
              () -> {
                configCategoryProxy.name().like(searchReq.getKeyword());
                configCategoryProxy.code().like(searchReq.getKeyword());
              });
        });
  }

  @Override
  protected EasyEntityQuery easyEntityQuery() {
    return easyEntityQuery;
  }
}
